package com.example.base_model.network.error

import android.util.MalformedJsonException
import kotlinx.coroutines.TimeoutCancellationException
import org.json.JSONException
import retrofit2.HttpException
import java.io.EOFException
import java.io.IOException
import java.net.ConnectException
import java.net.NoRouteToHostException
import java.net.ProtocolException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import javax.net.ssl.SSLException
import kotlin.coroutines.cancellation.CancellationException

/**
 * @Author jiangKunKun
 * @CreateDate 2025/7/14
 * @Description 异常映射器单例，负责将各种网络相关的 [Throwable] 异常转换为统一的、可处理的 [NetworkRequestError] 枚举。
 * 这样做的好处是，UI 层或业务逻辑层无需关心具体的异常类型，只需处理预定义的错误类型即可。
 * @SpittingGrooves
 */
object ExceptionMapper {
    /**
     * 将给定的 [Throwable] 映射为一个 [NetworkRequestError] 枚举值。
     *
     * @param throwable 从网络请求层（如 Retrofit, OkHttp）或协程中捕获的原始异常。
     * @return 映射后的 [NetworkRequestError] 枚举，代表了一个具体的错误类别。
     */
    fun mapToApiError(throwable: Throwable): NetworkRequestError {
        return when (throwable) {
            // === 网络连接相关异常 ===
            // 通常表示设备没有网络连接，或者无法通过 DNS 解析主机名。
            is UnknownHostException,
            // 表示无法建立 TCP 连接（例如，服务器拒绝连接或地址不正确）。
            is ConnectException,
            // 表示没有到达目标的路由（例如，网络配置错误或防火墙阻止）。
            is NoRouteToHostException -> NetworkRequestError.NETWORK

            // === 超时相关 ===
            // 表示在建立连接或读取数据时，等待时间超过了 OkHttp 设置的超时阈值。
            is SocketTimeoutException,
            // 协程的超时，通常由 `withTimeout` 块触发。
            is TimeoutCancellationException -> NetworkRequestError.TIMEOUT

            // === IO 相关异常 ===
            // 表示在读取或写入数据流时发生问题，例如服务器提前关闭了响应体。
            is IOException,
            // 是 `IOException` 的一个特例，表示在读取数据时意外到达了文件或流的末尾。
            is EOFException -> NetworkRequestError.IO_ERROR

            // === JSON 解析异常 ===
            // 表示响应的 JSON 格式不正确或与期望的数据模型不匹配。
            is JSONException,
            is MalformedJsonException,
            is com.squareup.moshi.JsonDataException -> NetworkRequestError.PARSING

            // === HTTP 错误码（由 Retrofit 封装） ===
            is HttpException -> {
                // 当服务器返回一个非 2xx 的 HTTP 状态码时，Retrofit 会抛出此异常。
                if (throwable.code() in 400..599) {
                    // 4xx（客户端错误）和 5xx（服务器错误）通常都归为服务器端问题。
                    NetworkRequestError.SERVER_ERROR
                } else {
                    // 其他非 2xx 范围的错误码（虽然少见），归为未知错误。
                    NetworkRequestError.UNKNOWN
                }
            }

            // === SSL/TLS 证书错误 ===
            // 表示在进行 HTTPS 握手时发生错误，例如证书无效、过期或不受信任。
            is SSLException -> NetworkRequestError.SSL_ERROR

            // === 协程取消 ===
            // 当一个协程作业被主动取消时抛出。这不一定是一个“错误”，但需要正确处理以停止后续流程。
            is CancellationException,
            // 当一个线程在等待、休眠或被占用时被中断。在协程中，通常被包装在 `CancellationException` 中。
            is InterruptedException -> NetworkRequestError.CANCELLED

            // === 协议错误 ===
            // 表示在 HTTP 协议层面发生错误，例如服务器返回了格式不正确的响应头。
            is ProtocolException -> NetworkRequestError.PROTOCOL_ERROR

            // === 其他所有未明确处理的异常 ===
            else -> NetworkRequestError.UNKNOWN
        }
    }
}
